package com.chuangjiangx.member.manager.web.web.basic.controller;

import com.chuangjiangx.commons.CJBeanUtils;
import com.chuangjiangx.commons.JacksonUtils;
import com.chuangjiangx.commons.PageUtils;
import com.chuangjiangx.commons.page.PagingResult;
import com.chuangjiangx.commons.request.Page;
import com.chuangjiangx.commons.response.Response;
import com.chuangjiangx.commons.response.ResponseUtils;
import com.chuangjiangx.commons.sms.SMSUtils;
import com.chuangjiangx.member.basic.ddd.application.EntryApplication;
import com.chuangjiangx.member.basic.ddd.application.MbrSmsApplication;
import com.chuangjiangx.member.basic.ddd.application.MemberApplication;
import com.chuangjiangx.member.basic.ddd.application.command.ModifyMemberCommand;
import com.chuangjiangx.member.basic.ddd.application.command.ModifyMobileCommand;
import com.chuangjiangx.member.basic.ddd.domain.model.MbrSourceTerminal;
import com.chuangjiangx.member.basic.ddd.query.MemberQuery;
import com.chuangjiangx.member.basic.ddd.query.MerchantInfoQuery;
import com.chuangjiangx.member.basic.ddd.query.MerchantUserInfoQuery;
import com.chuangjiangx.member.basic.ddd.query.condition.MemberCondition;
import com.chuangjiangx.member.basic.ddd.query.condition.QueryMemberAccountCondition;
import com.chuangjiangx.member.basic.ddd.query.condition.QueryMemberInfoCondition;
import com.chuangjiangx.member.basic.ddd.query.dto.MemberDetailForMerchantDTO;
import com.chuangjiangx.member.basic.ddd.query.dto.MemberListDTO;
import com.chuangjiangx.member.basic.ddd.query.dto.UserInfoDTO;
import com.chuangjiangx.member.coupon.ddd.application.command.CancelMemberCommand;
import com.chuangjiangx.member.manager.basic.web.controller.BaseController;
import com.chuangjiangx.member.manager.basic.web.interceptor.Login;
import com.chuangjiangx.member.manager.basic.web.interceptor.Permissions;
import com.chuangjiangx.member.manager.client.web.basic.request.CheckPhone;
import com.chuangjiangx.member.manager.common.CodeUtils;
import com.chuangjiangx.member.manager.common.Constants;
import com.chuangjiangx.member.manager.common.RequestHeadersUtil;
import com.chuangjiangx.member.manager.common.ThreadLocalUser;
import com.chuangjiangx.member.manager.common.utils.StrUtils;
import com.chuangjiangx.member.manager.web.web.basic.request.*;
import com.chuangjiangx.member.manager.web.web.basic.response.*;
import com.chuangjiangx.member.manager.web.web.score.request.ScoreDetailListRequest;
import com.chuangjiangx.member.manager.web.web.score.response.MemberScoreGiftResponse;
import com.chuangjiangx.member.manager.web.web.score.response.MemberScoreResponse;
import com.chuangjiangx.member.manager.web.web.score.response.ScoreDetailListResponse;
import com.chuangjiangx.member.manager.web.web.stored.request.StoredDetailListRequest;
import com.chuangjiangx.member.manager.web.web.stored.response.MerchantStoredDetailListResponse;
import com.chuangjiangx.member.manager.web.web.stored.response.StoreNameForListResponse;
import com.chuangjiangx.member.score.ddd.dal.condition.MemberScoreGiftCondition;
import com.chuangjiangx.member.score.ddd.dal.condition.ScoreStreamListCondition;
import com.chuangjiangx.member.score.ddd.query.MbrScoreStreamQuery;
import com.chuangjiangx.member.score.ddd.query.dto.MemberScoreDTO;
import com.chuangjiangx.member.score.ddd.query.dto.MemberScoreGiftDTO;
import com.chuangjiangx.member.score.ddd.query.dto.MerchantStoredStreamListDTO;
import com.chuangjiangx.member.score.ddd.query.dto.ScoreStreamForMerchantDTO;
import com.chuangjiangx.member.stored.ddd.dal.condition.QueryMerchantStoredListCondition;
import com.chuangjiangx.member.stored.ddd.query.MbrStoredStreamQuery;
import com.chuangjiangx.member.stored.ddd.query.dto.MemberStoredDTO;
import com.chuangjiangx.member.stored.ddd.query.dto.StoreNameForListDTO;
import com.chuangjiangx.privileges.olddao.dto.MerchantUserCommon;
import com.cloudrelation.partner.platform.model.AgentClientToken;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.jmx.snmp.ThreadContext;
import lombok.extern.java.Log;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 会员操作
 */
@RestController
@Log
@RequestMapping(value = "/api/mbr/member", produces = "application/json")
public class MemberController extends BaseController {
    @Autowired
    private MemberQuery memberQuery;
    @Autowired
    private MemberApplication memberApplication;
    @Autowired
    private MbrScoreStreamQuery mbrScoreStreamQuery;

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private MbrStoredStreamQuery mbrStoredStreamQuery;

    @Autowired
    private MbrSmsApplication mbrSmsApplication;

    @Autowired
    private EntryApplication entryApplication;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private MerchantUserInfoQuery merchantUserInfoQuery;
    @Autowired
    private MerchantInfoQuery merchantInfoQuery;


    @Value("${wxPay.activity.sign.in.callback}")
    private String activitySignInCallback;

    @Value("#{configProperties['wxPay.sqURL.T']}")
    private String oauth2ReqHead;

    @Value("${wx.public.appId}")
    private String appId;


    /**
     * 测试spring-session
     * @param req
     * @return
     */
    @RequestMapping("/test-session/{age}")
    @ResponseBody
    public CheckPhone TestSession(HttpServletRequest req){

        CheckPhone condition = new CheckPhone();
        condition.setPhone("123432");
        req.getSession().setAttribute("age", condition);
        CheckPhone a = (CheckPhone) req.getSession().getAttribute("age");
        return a;
    }


    /**
     * 会员列表
     *
     * @param param   模糊查询条件
     * @map memberList
     * @see MemberListResponse
     */
    @RequestMapping(value = "/member-list", produces = "application/json")
    @Login
    @Permissions("54000")
    public Response memberList(@Validated @RequestBody MemberListRequest param) {

        MemberCondition condition = new MemberCondition();
        BeanUtils.copyProperties(param, condition);
        PageUtils.copyPage(condition, param.getPage());

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(user.getMerchantId());

        PagingResult<MemberListDTO> memberRs = memberQuery.queryMemberList(condition);
        List<MemberListResponse> respList = CJBeanUtils
                .convertCollection(memberRs.getItems(), MemberListResponse.class, (source, target) -> {
                    target.setAvailableScore(source.getAvailableScore().longValue());
                    target.setMobile(StrUtils.encodeMobilePhone(source.getMobile()));
                });

        return ResponseUtils.successPage(param.getPage(), memberRs, "memberList", respList);
    }

    /**
     * 会员列表 导出
     */
    @RequestMapping(value = "/export/member-list", produces = "application/json")
    @Login
    public void exportMemberList(HttpServletResponse response, HttpServletRequest request) throws IOException, ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat lastDateSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String nameOrMobileNum = request.getParameter("nameOrMobileNum");
        String pageNo = request.getParameter("pageNO");
        String everyPageCount = request.getParameter("everyPageCount");
        MemberListRequest param = new MemberListRequest();
        if (StringUtils.isNotBlank(startTime)) {
            param.setStartRegisterTime(sdf.parse(startTime));
        }
        if (StringUtils.isNotBlank(endTime)) {
            param.setEndRegisterTime(sdf.parse(endTime));
        } else {
            param.setEndRegisterTime(new Date());
        }
        if (StringUtils.isNotBlank(nameOrMobileNum)) {
            param.setNameOrMobile(nameOrMobileNum);
        }
        Page page = new Page();
        if (StringUtils.isNotBlank(pageNo)) {
            page.setPageNO(Integer.parseInt(pageNo));
        }
        if (StringUtils.isNotBlank(everyPageCount)) {
            page.setEveryPageCount(EXPORT_SIZE);
        }
        param.setPage(page);
        OutputStream out = response.getOutputStream();
        RequestHeadersUtil.exportRequestHeader(response, "会员列表");
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {

            //获取商户会员列表导出数据
            MemberCondition condition = new MemberCondition();
            BeanUtils.copyProperties(param, condition);
            PageUtils.copyPage(condition, param.getPage());
            ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);

            condition.setMerchantId(user.getMerchantId());
            PagingResult<MemberListDTO> memberRs = memberQuery.queryMemberList(condition);
            List<MemberListResponse> list = CJBeanUtils
                    .convertCollection(memberRs.getItems(), MemberListResponse.class, (source, target) -> {
                        target.setAvailableScore(source.getAvailableScore().longValue());
                        target.setMobile(StrUtils.encodeMobilePhone(source.getMobile()));
                    });


            osw = new OutputStreamWriter(out, "GBK");
            bw = new BufferedWriter(osw);
            bw.append("序号").append(",")
                    .append("会员卡号").append(",")
                    .append("会员名称").append(",")
                    .append("手机号码").append(",")
                    .append("储值余额").append(",")
                    .append("可用积分").append(",")
                    .append("最近消费时间").append(",").append("\r");
            if (list != null && !list.isEmpty()) {
                for (int i = 0; i < list.size(); i++) {
                    MemberListResponse data = list.get(i);
                    String latestStoredDate = null;
                    if (data.getLatestStoredDate() != null) {
                        latestStoredDate = lastDateSdf.format(data.getLatestStoredDate());
                    }
                    bw.append(String.valueOf(i + 1)).append(",")
                            .append(data.getMemberCardNum() == null ? "" : data.getMemberCardNum()).append(",")
                            .append(data.getName() == null ? "" : data.getName()).append(",")
                            .append(data.getMobile() == null ? "" : data.getMobile()).append(",")
                            .append(data.getAvailableBalance() == null ? "" : data.getAvailableBalance().toString()).append(",")
                            .append(data.getAvailableScore() == null ? "" : data.getAvailableScore().toString()).append(",")
                            .append(latestStoredDate == null ? "" : latestStoredDate).append(",").append("\r");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                bw.close();
                bw = null;
            }
            if (osw != null) {
                osw.close();
                osw = null;
            }
            if (out != null) {
                out.close();
                out = null;
            }
        }
    }

//    private List<MemberListResponse> getMemberListResponses(HttpSession session, MemberListRequest param) throws Exception {
//        MemberCondition condition = new MemberCondition();
//        BeanUtils.copyProperties(param, condition);
//        PageUtils.copyPage(condition, param.getPage());
//
//        MerchantUserCommon user = getUser(session);
//        condition.setMerchantId(user.getMerchantId());
//        List<MemberListResponse> listResponses = new ArrayList<>();
//        if (param.getStartRegisterTime() == null || param.getEndRegisterTime() == null) {
//            if (StringUtils.isNotBlank(param.getNameOrMobile())) {
//                PagingResult<MemberListDTO> memberRs = memberQuery.queryMemberList(condition);
//                listResponses = CJBeanUtils.convertCollection(memberRs.getItems(), MemberListResponse.class);
//            } else {
//                List<MemberListDTO> list = memberQuery.queryMemberListAll(user.getMerchantId());
//                if (list.size() <= EXPORT_SIZE) {
//                    listResponses = CJBeanUtils.convertCollection(list, MemberListResponse.class);
//                } else {
//                    throw new Exception("最多可支持导出10000条数据");
//                }
//            }
//
//
//        } else {
//            PagingResult<MemberListDTO> memberRs = memberQuery.queryMemberList(condition);
//            listResponses = CJBeanUtils.convertCollection(memberRs.getItems(), MemberListResponse.class);
//        }
//
//        return listResponses;
//    }

    /**
     * 根据id 查询会员信息
     *
     * @param memberInfoRequest 会员id
     * @map member
     * @see MemberVolumeDetailResponse
     */
    @RequestMapping(value = "/member-by-id")
    @Login
    @Permissions("54001")
    public Response memberById(@RequestBody @Validated SearchMemberInfoRequest memberInfoRequest) {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);

        QueryMemberInfoCondition condition = new QueryMemberInfoCondition();
        condition.setMerchantId(user.getMerchantId());
        condition.setMemberId(memberInfoRequest.getId());

        MemberDetailForMerchantDTO dto = memberQuery.queryMemberDetailById(condition);
        MemberDetailForMerchantResponse response = new MemberDetailForMerchantResponse();
        CJBeanUtils.convertBean(dto, response);
        if (response.getRegisterStoreName() == null) {
            response.setRegisterStoreName(user.getMerchantName());
        }
        response.setMobile(StrUtils.encodeMobilePhone(dto.getMobile()));
        return ResponseUtils.success("memberInfo", response);
    }

    /**
     * 修改会员手机号
     *
     * @param param   请求参数
     * @return 修改结果
     * @throws Exception
     */
    @RequestMapping(value = "/modify-member-mobile")
    @Login
    @Permissions("54004")
    public Response modifyByMobile(
                                   @Validated @RequestBody ModifyByMobileRequest param) throws Exception {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);

        ModifyMobileCommand command = new ModifyMobileCommand(
                param.getMemberId(),
                param.getMobile(),
                user.getMerchantId(),
                user.getStoreId(),
                user.getStoreUserId(),
                MbrSourceTerminal.MERCHANT_WEB.value,
                null,
                user.getMerchantUserId());

        memberApplication.modifyMobile(command);
        return ResponseUtils.success();
    }

    /**
     * 修改会员信息（包含手机号）
     *
     * @param param   请求参数
     * @return 修改结果
     * @throws Exception
     */
    @RequestMapping(value = "/modify-member-info")
    @Login
    @Permissions("54002")
    public Response modifyMemberInfo(
                                     @Validated @RequestBody ModifyMemberRequest param) throws Exception {
        if (StringUtils.isNotBlank(param.getMobile())) {
            if (StringUtils.isNotBlank(param.getVerifyCode())) {
                // 校验短信验证码是否正确
                if (!SMSUtils.codeCheck(param.getMobile(), param.getVerifyCode(), redisTemplate)) {
                    throw new IllegalArgumentException("短信验证码错误");
                }
            } else {
                throw new IllegalArgumentException("没有填写短信验证码");
            }
        }

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        ModifyMemberCommand command = new ModifyMemberCommand(
                param.getMemberId(),
                param.getName(),
                param.getSex(),
                param.getBirthday(),
                user.getMerchantId(),
                user.getStoreId(),
                user.getStoreUserId(),
                null,
                null,
                param.getMobile(),
                user.getMerchantUserId());

        memberApplication.modifyMember(command);
        return ResponseUtils.success();
    }

    /**
     * 删除会员
     *
     * @param memberInfoRequest 请求参数
     * @return 删除结果
     * @throws Exception
     */
    @RequestMapping(value = "/delete-member")
    @Login
    // @Permissions("54003")
    public Response deleteMember(@Validated @RequestBody DeleteMemberInfoRequest memberInfoRequest) throws Exception {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        CancelMemberCommand command = new CancelMemberCommand(
                memberInfoRequest.getId(),
                user.getMerchantId(),
                user.getStoreId(),
                user.getStoreUserId(),
                MbrSourceTerminal.MERCHANT_WEB.value,
                null,
                user.getMerchantUserId());

        memberApplication.cancelMember(command);
        return ResponseUtils.success();
    }

    /**
     * 查询会员储值余额，储值总额
     *
     * @param storedRequest 会员id
     * @param session       获取用户信息session
     * @return 查询结果
     */
    @RequestMapping(value = "/searchMemberStored")
    @Login
    //@Permissions("")
    public Response searchMemberStored(@Validated @RequestBody SearchMemberStoredRequest storedRequest, HttpSession session) {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        QueryMemberAccountCondition condition = new QueryMemberAccountCondition();
        condition.setMemberId(storedRequest.getId());
        condition.setMerchantId(user.getMerchantId());

        MemberStoredResponse response = new MemberStoredResponse();
        MemberStoredDTO dto = memberQuery.queryMemberStoredForClient(condition);
        CJBeanUtils.convertBean(dto, response);

        return ResponseUtils.success("meberStored", response);
    }

    /**
     * 查询会员储值明细列表
     *
     * @param storedRequest 请求参数
     * @param session       获取用户信息session
     * @map storedDetailList
     * @see MerchantStoredDetailListResponse
     */
    @RequestMapping(value = "/stored-detail-list")
    @Login
    public Response searchMemberStoredList(@RequestBody @Validated StoredDetailListRequest storedRequest, HttpSession session) {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        QueryMerchantStoredListCondition condition = new QueryMerchantStoredListCondition();

        condition.setMerchantId(user.getMerchantId());
        condition.setMemberId(storedRequest.getMemberId());
        condition.setStartTime(storedRequest.getStartTime());
        condition.setEndTime(storedRequest.getEndTime());
        condition.setType(storedRequest.getType());
        condition.setStoredNum(storedRequest.getStoredNum());
        condition.setStoreName(storedRequest.getStoreName());
        PageUtils.copyPage(condition, storedRequest.getPage());

        PagingResult<MerchantStoredStreamListDTO> list = mbrStoredStreamQuery.searchStoredStreamListForMerchant(condition);
        List<MerchantStoredDetailListResponse> respList = CJBeanUtils.convertCollection(list.getItems(), MerchantStoredDetailListResponse.class, (source, target) -> {
            if (source.getStoreUserName() == null) {
                target.setStoreUserName(user.getMerchantName());
            }
        });

        return ResponseUtils.successPage(storedRequest.getPage(), list, "storedDetailList", respList);
    }


    /**
     * 会员储值明细列表 导出
     */
    @RequestMapping(value = "/export/stored-detail-list", produces = "application/json")
    @Login
    public void exportSearchMemberStoredList(HttpServletRequest request, HttpServletResponse response) throws IOException, ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String storedNum = request.getParameter("storedNum");
        String storeName = request.getParameter("storeName");
        String memberId = request.getParameter("memberId");
        String type = request.getParameter("type");
        String pageNo = request.getParameter("pageNO");
        StoredDetailListRequest param = new StoredDetailListRequest();
        if (!"".equals(startTime)) {
            param.setStartTime(sdf.parse(startTime));
        }
        if (!"".equals(endTime)) {
            param.setEndTime(sdf.parse(endTime));
        }

        if (!"".equals(storedNum)) {
            param.setStoredNum(storedNum);
        }
        if (!"".equals(storeName)) {
            param.setStoreName(storeName);
        }
        if (!"".equals(type)) {
            param.setType(Byte.valueOf(type));
        }
        if (!"".equals(memberId)) {
            param.setMemberId(Long.parseLong(memberId));
        }
        Page page = new Page();
        if (!"".equals(pageNo)) {
            page.setPageNO(Integer.parseInt(pageNo));
        }
        page.setEveryPageCount(EXPORT_SIZE);
        param.setPage(page);

        OutputStream out = response.getOutputStream();
        RequestHeadersUtil.exportRequestHeader(response, "会员储值明细列表");

        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            List<MerchantStoredDetailListResponse> list = getExportSearchMemberStoredList(param);
            osw = new OutputStreamWriter(out, "GBK");
            bw = new BufferedWriter(osw);
            bw.append("序号").append(",")
                    .append("交易单号").append(",")
                    .append("交易时间").append(",")
                    .append("交易类型").append(",")
                    .append("交易金额").append(",")
                    .append("赠送金额").append(",")
                    .append("交易后余额").append(",")
                    .append("支付方式").append(",")
                    .append("\r");
            if (list != null && !list.isEmpty()) {
                for (int i = 0; i < list.size(); i++) {
                    MerchantStoredDetailListResponse data = list.get(i);
                    String dateTime = null;
                    if (data.getDateTime() != null) {
                        dateTime = sdf.format(data.getDateTime());
                    }
                    bw.append(String.valueOf(i + 1)).append(",")
                            .append(data.getStoredNum() == null ? "" : getCompleteExcelString(data.getStoredNum())).append(",")
                            .append(dateTime).append(",")
                            .append(data.getTypeText() == null ? "" : data.getTypeText()).append(",")
                            .append(data.getTransactionAmount() == null ? "" : data.getTransactionAmount().toString()).append(",")
                            .append(data.getGiftAmount() == null ? "" : data.getGiftAmount().toString()).append(",")
                            .append(data.getPostTradingBalance() == null ? "" : data.getPostTradingBalance().toString()).append(",")
                            .append(data.getPayTypeText() == null ? "" : data.getPayTypeText()).append(",")
                            .append("\r");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                bw.close();
            }
            if (osw != null) {
                osw.close();
            }
            if (out != null) {
                out.close();
            }
        }

    }

    private List<MerchantStoredDetailListResponse> getExportSearchMemberStoredList(StoredDetailListRequest storedRequest) {
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        QueryMerchantStoredListCondition condition = new QueryMerchantStoredListCondition();
        condition.setMerchantId(user.getMerchantId());
        condition.setMemberId(storedRequest.getMemberId());
        condition.setStartTime(storedRequest.getStartTime());
        condition.setEndTime(storedRequest.getEndTime());
        condition.setType(storedRequest.getType());
        condition.setStoredNum(storedRequest.getStoredNum());
        condition.setStoreName(storedRequest.getStoreName());
        PageUtils.copyPage(condition, storedRequest.getPage());
        PagingResult<MerchantStoredStreamListDTO> list = mbrStoredStreamQuery.searchStoredStreamListForMerchant(condition);
        return CJBeanUtils.convertCollection(list.getItems(), MerchantStoredDetailListResponse.class);
    }

    /**
     * 查询会员可用积分、历史累计积分
     *
     * @param session       获取用户信息session
     * @param storedRequest 请求参数
     * @map memberCardStore
     * @see CountByMerchantIdAndMemberIdResponse
     */
    @RequestMapping(value = "/member-by-count-merchantId-and-memberId")
    @Login
    @Permissions("54006")
    public Response searchMemberScore(HttpSession session, @Validated @RequestBody SearchMemberStoredRequest storedRequest) {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        QueryMemberAccountCondition condition = new QueryMemberAccountCondition();
        condition.setMemberId(storedRequest.getId());
        condition.setMerchantId(user.getMerchantId());

        MemberScoreDTO dto = memberQuery.queryMemberScoreForClient(condition);
        Assert.notNull(dto, "会员不存在！");

        MemberScoreResponse response = new MemberScoreResponse();
        response.setAvailableScore(dto.getAvailableScore().longValue());
        response.setTotalScore(dto.getTotalScore().longValue());

        return ResponseUtils.success("memberScore", response);
    }

    /**
     * 当前会员-积分明细列表查询
     *
     * @param param   请求参数
     * @param session 获取用户信息session
     * @map dataList
     * @see ScoreDetailListResponse
     */
    @RequestMapping(value = "/score-detail-list")
    @Login
    @Permissions("54005")
    public Response scoreDetailList(HttpSession session, @Validated @RequestBody ScoreDetailListRequest param) {

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        ScoreStreamListCondition condition = new ScoreStreamListCondition(
                user.getMerchantId(),
                param.getMemberId(),
                param.getStartTime(),
                param.getEndTime(),
                param.getType()
        );
        PageUtils.copyPage(condition, param.getPage());

        PagingResult<ScoreStreamForMerchantDTO> platformDetailList = mbrScoreStreamQuery.searchScoreStreamListForMerchant(condition);
        List<ScoreDetailListResponse> respList = CJBeanUtils.convertCollection(platformDetailList.getItems(), ScoreDetailListResponse.class, (source, target) -> {
            if (source.getStoreUserName() == null) {
                target.setStoreUserName(user.getMerchantName());
            }
            if (source.getAvailableScore() == null) {
                target.setAvailableScore(0L);
            }
        });

        return ResponseUtils.successPage(param.getPage(), platformDetailList, "scoreDetailList", respList);
    }


    /**
     * 当前会员-积分明细列表查询 导出
     */
    @RequestMapping(value = "/export/score-detail-list", produces = "application/json")
    @ResponseBody
    @Login
    public void exportScoreDetailList(HttpSession session, HttpServletResponse response, HttpServletRequest request) throws IOException, ParseException {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String type = request.getParameter("type");
        String memberId = request.getParameter("memberId");
        String pageNo = request.getParameter("pageNO");
        ScoreDetailListRequest param = new ScoreDetailListRequest();
        if (!"".equals(startTime)) {
            param.setStartTime(sdf.parse(startTime));
        }
        if (!"".equals(endTime)) {
            param.setEndTime(sdf.parse(endTime));
        }
        if (!"".equals(type)) {
            param.setType(Byte.valueOf(type));
        }
        if (!"".equals(memberId)) {
            param.setMemberId(Long.parseLong(memberId));
        }
        Page page = new Page();
        if (!"".equals(pageNo)) {
            page.setPageNO(Integer.parseInt(pageNo));
        }
        page.setEveryPageCount(EXPORT_SIZE);
        param.setPage(page);

        OutputStream out = response.getOutputStream();
        RequestHeadersUtil.exportRequestHeader(response, "积分明细列表");

        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            List<ScoreDetailListResponse> list = getExportScoreDetailList(session, param);
            osw = new OutputStreamWriter(out, "GBK");
            bw = new BufferedWriter(osw);
            bw.append("序号").append(",")
                    .append("交易时间").append(",")
                    .append("积分类型").append(",")
                    .append("交易积分").append(",")
                    .append("交易后积分").append(",")
                    .append("\r");

            if (list != null && !list.isEmpty()) {
                for (int i = 0; i < list.size(); i++) {
                    ScoreDetailListResponse data = list.get(i);
                    String createTime = null;
                    if (data.getCreateTime() != null) {
                        createTime = sdf.format(data.getCreateTime());
                    }
                    bw.append(String.valueOf(i + 1)).append(",")
                            .append(createTime).append(",")
                            .append(data.getTypeText() == null ? "" : data.getTypeText()).append(",")
                            .append(data.getScore() == null ? "" : data.getScore().toString()).append(",")
                            .append(data.getAvailableScore() == null ? "" : data.getAvailableScore().toString()).append("\r");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                bw.close();
                bw = null;
            }
            if (osw != null) {
                osw.close();
                osw = null;
            }
            if (out != null) {
                out.close();
                out = null;
            }
        }


    }

    private List<ScoreDetailListResponse> getExportScoreDetailList(HttpSession session, @Validated @RequestBody ScoreDetailListRequest param) {
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);        ScoreStreamListCondition condition = new ScoreStreamListCondition(
                user.getMerchantId(),
                param.getMemberId(),
                param.getStartTime(),
                param.getEndTime(),
                param.getType()
        );

        List<ScoreDetailListResponse> list = new ArrayList<>();
        if (param.getStartTime() == null || param.getEndTime() == null) {
            if (param.getType() != null) {
                PageUtils.copyPage(condition, param.getPage());
                PagingResult<ScoreStreamForMerchantDTO> listDto = mbrScoreStreamQuery.searchScoreStreamListForMerchant(condition);
                list = CJBeanUtils.convertCollection(listDto.getItems(), ScoreDetailListResponse.class);
            } else {
                List<ScoreStreamForMerchantDTO> listDto = mbrScoreStreamQuery.queryScoreStreamListAll(condition);
                list = CJBeanUtils.convertCollection(listDto, ScoreDetailListResponse.class);
            }

        } else {
            PageUtils.copyPage(condition, param.getPage());
            PagingResult<ScoreStreamForMerchantDTO> listDto = mbrScoreStreamQuery.searchScoreStreamListForMerchant(condition);
            list = CJBeanUtils.convertCollection(listDto.getItems(), ScoreDetailListResponse.class);
        }

        return list;
    }


    /**
     * 发送短信验证码
     *
     * @param mobile 手机号码
     */
    @RequestMapping(value = "/send-code")
    @Login
    @Permissions("54008")
    public Response sendCode(@Param(value = "mobile") String mobile) throws Exception {
//        String code = SMSUtils.sendCodeInfo(mobile, redisTemplate);//短信摸模板
//        redisService.pushRongLianSMS(mobile, 2, null, code);//推送模板
//        SMSUtils.saveCodeInfo(mobile, code, redisTemplate);
        mbrSmsApplication.sendMobileVerifyCode(mobile);
        return ResponseUtils.success();
    }


    /**
     * 根据会员id查询会员兑换记录信息
     *
     * @map dataList
     * @see MemberScoreGiftResponse
     */
    @RequestMapping(value = "/member-by-score-gift-info-id")
    @Login
    @Permissions("54007")
    public Response memberScoreGiftList(HttpSession session, @Validated @RequestParam(value = "id") Long id) {
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        MemberScoreGiftCondition condition = new MemberScoreGiftCondition();
        condition.setMemberId(id);
        condition.setMerchantId(user.getMerchantId());

        PagingResult<MemberScoreGiftDTO> pagingResult = memberQuery.queryMemberScoreGiftList(condition);
        List<MemberScoreGiftResponse> list = CJBeanUtils.convertCollection(pagingResult.getItems(), MemberScoreGiftResponse.class);
        return ResponseUtils.success("dataList", list);
    }

    /**
     * 所有门店
     *
     * @map dataList
     * @see StoreNameForListResponse
     */
    @RequestMapping(value = "/all-store-name")
    @Login
    public Response getAllStoreName(HttpSession session) {
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        List<StoreNameForListDTO> list = memberQuery.queryAllStoreName(null, user.getMerchantId());
        List<StoreNameForListResponse> responses = CJBeanUtils.convertCollection(list, StoreNameForListResponse.class);
        return ResponseUtils.success("dataList", responses);
    }

    /**
     * h5链接
     * 需要兼容登录和未登录两种方式
     */
    @RequestMapping(value = "/h5link")
    public Response getH5Link(
            HttpServletRequest request,
            HttpSession session,
            @RequestParam(required = false) Long merchantId) {
        Long mid = merchantId;
        if(mid == null){
            String tokenStr = request.getHeader(Constants.TOKEN_STR);
            Long merchantUserId;
            if(StringUtils.isNotBlank(tokenStr)){
                // client访问
                AgentClientToken agentClientToken = JacksonUtils.toObject(objectMapper,redisTemplate.opsForValue().get(tokenStr), AgentClientToken.class);
                if (agentClientToken == null) {
                    return ResponseUtils.error("","无法获取商户Id");
                }
                merchantUserId = agentClientToken.getMerchantUserId();
            }else{
                // web访问
                MerchantUserCommon merchantUserCommon = (MerchantUserCommon) request.getSession().getAttribute(BaseController.SESSION_USER);
                if(null == merchantUserCommon){
                    return ResponseUtils.error("","无法获取商户Id");
                }
                merchantUserId = merchantUserCommon.getId();
            }
            UserInfoDTO userInfoDTO = merchantUserInfoQuery.queryUserInfo(merchantUserId);
            mid = userInfoDTO.getMerchantId();
        }else{
            //校验merchantId
            Long defaultMerchantUserId = merchantUserInfoQuery.getDefaultMerchantUserId(mid);
            if(defaultMerchantUserId == null){
                return ResponseUtils.error("","无效的商户Id");
            }
        }

        String url = entryApplication.h5EntryUrl(mid);
        String qrcode = CodeUtils.generateQrCode(url);
        H5LinkDataResponse response = new H5LinkDataResponse();
        response.setQrcode(qrcode);
        response.setUrl(url);
        return ResponseUtils.success(response);
    }

//    /**
//     * 标记操作
//     * @param labelRequest
//     * @return 响应
//     */
//    @RequestMapping(value = "/view-label")
//    public Response redirectionLabel(MemberViewLabelRequest labelRequest) {
//        String redisKey = RedisKeyManager.MBR_H5_LABEL;
//        if (labelRequest.getViewType() != null && labelRequest.getViewType() == 1) {
//            redisKey = RedisKeyManager.MBR_H5_LABEL + "JOIN_MEMBER_";
//        }
//        Byte operateType = labelRequest.getOperateType();
//        String openid = labelRequest.getOpenid();
//        Long merchantId = labelRequest.getMerchantId();
//        MemberViewLabelResponse labelResponse = new MemberViewLabelResponse();
//        if (operateType == 0) { //设置标记
//            redisTemplate.opsForValue().set(redisKey + openid + merchantId, getViewUrl(labelRequest),10, TimeUnit.MINUTES);
//        } else if (operateType == 1) { //获取标记
//            String url = redisTemplate.opsForValue().get(redisKey + openid + merchantId);
//            labelResponse.setViewUrl(url);
//        } else { //删除标记
//            if (redisTemplate.hasKey(redisKey + openid + merchantId)) {
//                redisTemplate.delete(redisKey + openid + merchantId);
//            }
//        }
//        return ResponseUtils.success(labelResponse);
//    }

    public String getViewUrl(MemberViewLabelRequest viewLabel) {
        String domain = System.getProperty("merchant.web.domain");
        StringBuilder url = new StringBuilder();
        url.append(domain);
        if (StringUtils.isNotBlank(viewLabel.getUserId())) {
            //用户扫动态二维码进入
            url.append("/api/redirect/pay-qrcode-redirect?userId=").append(viewLabel.getUserId())
                    .append("&totalFee=").append(viewLabel.getTotalFee())
                    .append("&channel=").append(viewLabel.getChannel());
            if (StringUtils.isNotBlank(viewLabel.getMemberId())) {
                url.append("&memberId=").append(viewLabel.getMemberId());
            }
            if (StringUtils.isNotBlank(viewLabel.getId())) {
                url.append("&id=").append(viewLabel.getId());
            }
        } else {
            //用户扫店铺中二维码进入
            url.append("/api/qrcode/commit?id=");
            if (viewLabel.getQrcodeId() != null) {
                url.append(viewLabel.getQrcodeId());
            }
            if (viewLabel.getOrderId() != null) {
                url.append("&orderId=").append(viewLabel.getOrderId());
            }
            if (viewLabel.getStoreUserId() != null) {
                url.append("&storeUserId=").append(viewLabel.getStoredRulesId());
            }
        }
        return url.toString();
    }


}
